package edu.gyc.hisecurity.auth;

import edu.gyc.hisecurity.model.Menu;

import edu.gyc.hisecurity.model.Role;
import edu.gyc.hisecurity.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;

@Component
@Slf4j
public class MyFilterSecuritySource implements FilterInvocationSecurityMetadataSource {
   @Autowired
   MenuService menuService;

    @Override //此方法根据用户请求url分析该url访问需要的角色

    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
      String  requestUrl=((FilterInvocation)o).getRequestUrl();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        //查出所有菜单url和对应角色
        List<Menu> menus =menuService.getAllMenusWithRole();
        log.info("MyFilterSecuritySource getAttributes called getAllMenusWithRole. current requestUrl {}",requestUrl);
  //遍历菜单的角色是否满足当前url角色的需求，满足就放到ConfigAttribute集合里备用
        for (Menu menu : menus) {
            if (antPathMatcher.match(menu.getPattern(), requestUrl)) {
                List<Role> roles=menu.getRoles();
                String[] rolesStr = new String[roles.size()];
                for (int i=0;i<roles.size();i++) {
                    rolesStr[i] = roles.get(i).getName();
                }
                return SecurityConfig.createList(rolesStr);
            }
        }
        return SecurityConfig.createList("ROLE_login"); //ROLE_login标记，表示用户登录了，只能
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
